import cloud from '@lafjs/cloud'
import nw from 'nw-lafjs'
import {RequestLog} from "@/common/requestLog";
//初始化数据库操作对象
const db = cloud.database()
const _ = db.command

export default async function (ctx: FunctionContext) {
  // 获取请求的实际IP
  const ip = ctx.headers['x-real-ip'] ? ctx.headers['x-real-ip'] : ctx.headers['x-forwarded-for']
  if (ip == "null") {
    ctx.response.status(403);
    ctx.response.json({ "code": 403, "msg": "访问受限，请联系管理员" })
    return false
  }

  // @ts-ignore
  const func = ctx.request.params.name
  const referer = ctx.headers['referer']
  // 添加请求IP到数据库，并自动添加 add_time
  RequestLog(ctx)
  //获取当前IP的时间段的访问次数
  const interval = 1 // 间隔分钟
  const times = 100 // 间隔Interval分钟内限制最大访问次数
  let timesRes = await nw.db.select({
    dbName: 'requestIp',
    getCount: true,
    pageIndex: 1,
    pageSize: times,
    // 主表where条件
    whereJson: {
      createdTime: _.and(_.gte(Date.now() - interval * 60 * 1000), _.lte(Date.now()))
    }
  })
  if (timesRes.total > times) {
    // 返回 false 则不会去继续请求实际的云函数
    ctx.response.status(403);
    ctx.response.json({ "code": 403, "msg": "请求太快啦，请稍后尝试" })
    return false
  }
  // 判断是否需要登录
  // 域名白名单，直接放行
  const whiteRefererList = [
    'https://laf.run/',// 这是在laf后台进行调试运行
  ]
  if (whiteRefererList.includes(referer)) {
    return true
  }
  // noauth目录下的接口，无需验证token，直接放行
  if (func.startsWith('noauth')) {
    return true
  }
  //单独接口放开逻辑，无需验证token
  const whiteAPI = [
    "admin/acl/index/registe",
    "admin/acl/index/login",
    "common/file",
    "wechat/user/weixin/wxLogin"
  ]
  if (whiteAPI.includes(func)){
    return true
  }
  //登录逻辑
  if (!ctx.user) {
    ctx.response.status(401);
    ctx.response.json({ "code": 401, "msg": "登录过期，请重新登录！" })
    return false
  }
  let token = ctx.headers['authorization']
  if (token) {
    token = token.replace('Bearer ', '')
  } else {
    ctx.response.status(401);
    ctx.response.json({ "code": 401, "msg": "登录过期，请重新登录" })
    return false
  }
  // 检查数据库是否存在token，只允许单点登录
  let app = func.startsWith("wechat")?"user":"admin"
  const res2 = await db.collection(app).where({
    token: token,
  }).getOne()
  if (!res2.data) {
    ctx.response.status(401);
    ctx.response.json({ "code": 401, "msg": "已在其他设备登录，请重新登录！" })
    return false
  }

  //是否需要权限校验




  return true
}
